package redis

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"log"
	"project-deploy-service/models"
	"strings"
)

type tokenService struct{}

var LoginUserKey = "login_user_key"
var LoginTokenKey = "login_tokens:"
var jwtKey = "VfmjYjd6Z1pOrlMS9r8szSS22c4U5elvu9drRaKIE3Rlu5eGMjM67BItmYDWqz7JrDMAC39RLvuM9vRHAJ9vYw=="

var TokenService tokenService

func (t *tokenService) GetLoginUser(token string) *models.LoginUserModel {
	claims, err := parseToken(token)
	if err != nil {
		return nil
	}
	ctx := context.Background()
	uuid, ok := claims[LoginUserKey].(string)
	if !ok {
		log.Fatalf("Claim %s is not a string", LoginUserKey)
	}
	userKey := getTokenKey(uuid)
	user, err := GetRedisClient().Get(ctx, userKey).Result()
	if err != nil {
		fmt.Println(err)
		return nil
	}
	var loginUser *models.LoginUserModel
	err = json.Unmarshal([]byte(user), &loginUser)
	if err != nil {
		log.Fatalf("Failed to unmarshal JSON: %v\n", err)
	}
	return loginUser
}

func getTokenKey(uuid string) string {
	return LoginTokenKey + uuid
}

func getSignKey(secret string) []byte {
	// Base64解码
	keyBytes, err := base64.StdEncoding.DecodeString(secret)
	if err != nil {
		log.Fatalf("Failed to decode secret: %v", err)
	}

	// 使用HMAC-SHA256生成密钥
	return keyBytes
}

// parseToken 解析并验证JWT token
func parseToken(tokenString string) (jwt.MapClaims, error) {
	tokenString = strings.Replace(tokenString, "Bearer ", "", 1)

	// 获取签名密钥
	signKey := getSignKey(jwtKey)

	// 解析token
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		// 验证token使用的签名方法
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}
		return signKey, nil
	})

	if err != nil {
		fmt.Println("Parse token error:", err)
		return nil, err
	}

	// 获取token中的声明（claims）
	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		return claims, nil
	} else {
		return nil, fmt.Errorf("invalid token")
	}
}
